package com.serviceprovider.business.module.admin.transaction.controller;

//~--- non-JDK imports --------------------------------------------------------

import com.serviceprovider.business.module.admin.transaction.valueobjects.AdminTransactionCriteria;
import com.serviceprovider.business.module.admin.transaction.valueobjects.ProcessTransactionVO;
import com.serviceprovider.business.module.admin.transaction.valueobjects.ProviderTransactionsSearch;
import com.serviceprovider.business.module.admin.user.services.dao.impl.UserService;
import com.serviceprovider.business.module.sp.transaction.model.TransactionDetail;
import com.serviceprovider.business.module.sp.transaction.services.interfaces.ITransactionService;
import com.serviceprovider.business.module.sp.transaction.valueobjects.TransactionDetailsVO;
import com.serviceprovider.business.module.user.model.impl.User;
import com.serviceprovider.business.utility.Int2DoublePropertyEditor;
import com.serviceprovider.business.utility.maintenance.settings.AppSettings;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

//~--- JDK imports ------------------------------------------------------------

import java.beans.PropertyEditor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class ProcessTransactionController extends SimpleFormController {
    ProviderTransactionsSearch searchModelObject;
    ProcessTransactionVO       searchedTransactionsModelObject;
    @Autowired
    ITransactionService        transactionService;
    @Autowired
    UserService                userService;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        PropertyEditor propertyEditorNullIsZero = new Int2DoublePropertyEditor(true);

        binder.registerCustomEditor(Integer.class, "transactionDetails.id", propertyEditorNullIsZero);
        binder.registerCustomEditor(Integer.class, "transactionDetails.traceNumber", propertyEditorNullIsZero);
        binder.registerCustomEditor(Integer.class, "transactionDetails.customerSSN", propertyEditorNullIsZero);
        binder.registerCustomEditor(Integer.class, "transactionDetails.amount", propertyEditorNullIsZero);
        logger.debug("initBinder finished");
    }

    private static Map<Integer, String> getStatusMap() {
        Map<Integer, String> transactionStatus = new HashMap<Integer, String>();

        transactionStatus.put(AppSettings.TRANSACTION_STATUS_NEW_ID, "New");
        transactionStatus.put(AppSettings.TRANSACTION_STATUS_DO_NOT_BELONG_TO_ME, "Do not belong to me");
        transactionStatus.put(AppSettings.TRANSACTION_STATUS_NEEDING_MATCH, "Needing a match");
        transactionStatus.put(AppSettings.TRANSACTION_STATUS_NEEDING_RETURN_BACK_TO_ORIGINATOR,
                              "Return back to originator");

        return transactionStatus;
    }

    @RequestMapping(
        value  = "/admin/transaction/search.htm",
        method = RequestMethod.GET
    )
    public ModelAndView getServiceProvider() {
        ModelAndView mav = null;

        mav = new ModelAndView("admin/transaction/process/processTransactions");

        ProviderTransactionsSearch search = new ProviderTransactionsSearch();

        search.setTransactionStatus(getStatusMap());
        mav.addObject("transactionsSearch", search);

        return mav;
    }

    @RequestMapping(
        value  = "/admin/transaction/search.htm",
        method = RequestMethod.POST
    )
    public ModelAndView searchTransactions(@ModelAttribute(
        value = "transactionsSearch") ProviderTransactionsSearch search) {
        List<TransactionDetail>    list     = new ArrayList<TransactionDetail>();
        List<TransactionDetailsVO> listVO   = new ArrayList<TransactionDetailsVO>();
        AdminTransactionCriteria   criteria = new AdminTransactionCriteria();

        criteria.setTransactionId(search.getTransactionId());
        criteria.setTraceId(search.getTransactionTraceNumber());
        criteria.setProviderFirstName(search.getProviderFirstName());
        criteria.setProviderLastName(search.getProviderLastName());
        criteria.setProviderSSN(search.getProviderSSN());
        criteria.setStatus(search.getSelectedTransactionStatus());
        list.addAll(transactionService.findByAdminCriteria(criteria));

        for (TransactionDetail transactionDetail : list) {
            User user = userService.getById(transactionDetail.getUserId());

            listVO.add(new TransactionDetailsVO(transactionDetail, user.getFirstName() + " " + user.getLastName()));
        }

        ModelAndView mav = new ModelAndView("admin/transaction/process/processTransactions");

        searchModelObject = search;

        ProcessTransactionVO               transactionVO = new ProcessTransactionVO();
        Map<Integer, TransactionDetailsVO> map           = new HashMap<Integer, TransactionDetailsVO>();
        int                                i             = 1;

        for (TransactionDetailsVO transactionDetailsVO : listVO) {
            map.put(i, transactionDetailsVO);
            i++;
        }

        transactionVO.setTransactionDetails(map);
        searchModelObject.setTransactionStatus(getStatusMap());
        searchedTransactionsModelObject = transactionVO;
        mav.addObject("transactionsSearch", searchModelObject);
        mav.addObject("searchedTransactions", transactionVO);

        return mav;
    }

    @RequestMapping(
        value  = "/admin/transaction/processTransactions.htm",
        method = RequestMethod.POST,
        params = "move_transactions"
    )
    public ModelAndView moveTransactionsToOtherProvider(@ModelAttribute(
        value = "searchedTransactions") ProcessTransactionVO form) {
        Map<Integer, TransactionDetailsVO> transactions = form.getTransactionDetails();
        Integer                            providerId   = form.getToProviderID();

        if ((providerId == null) || (providerId == 0)) {
            providerId = AppSettings.LOST_AND_FOUND_PROVIDER;
        }

        TransactionDetailsVO transactionDetailsVO = null;

        for (Integer key : transactions.keySet()) {
            transactionDetailsVO = transactions.get(key);

            if (transactionDetailsVO.getChecked()) {
                transactionService.moveTransactionToProvider(transactionDetailsVO.getId(), providerId);
            }
        }

        return searchTransactions(searchModelObject);
    }
}



